package com.wq.sofa.framework.rpc.boot.factory;

import com.alipay.sofa.rpc.boot.runtime.param.BoltBindingParam;
import com.alipay.sofa.runtime.api.aware.ClientFactoryAware;
import com.alipay.sofa.runtime.api.client.ClientFactory;
import com.alipay.sofa.runtime.api.client.ReferenceClient;
import com.alipay.sofa.runtime.api.client.param.BindingParam;
import com.alipay.sofa.runtime.api.client.param.ReferenceParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: wangqiang20995
 * @Date:2018/10/16
 * @Description:
 * @Resource:
 */
@Component
public class SofaServiceImportFactory implements ClientFactoryAware,ImportRpcService,ApplicationContextAware {

    private ClientFactory clientFactory;

    private ReferenceClient referenceClient;

    private Map<Class<?>,Object> cacheService;

    private Logger logger = LoggerFactory.getLogger(getClass());

    private ApplicationContext applicationContext;

    public SofaServiceImportFactory(){
        this.cacheService = new ConcurrentHashMap<>();
    }

    @Override
    public void setClientFactory(ClientFactory clientFactory) {
        this.clientFactory = clientFactory;
        this.referenceClient = clientFactory.getClient(ReferenceClient.class);
    }

    @Override
    public <T> T importService(Class<T> serviceType) {
        logger.info("import remote service --> [{}]",serviceType.getName());
        if(this.cacheService.containsKey(serviceType)){
            return (T) this.cacheService.get(serviceType);
        }

        ReferenceParam<T> referenceParam = new ReferenceParam<>();
        referenceParam.setInterfaceType(serviceType);

        BindingParam bindingParam = new BoltBindingParam();
        referenceParam.setBindingParam(bindingParam);

        return referenceClient.reference(referenceParam);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

        SofaServiceImportFactory sofaServiceImportFactory = applicationContext.getBean(SofaServiceImportFactory.class);
    }

    @Override
    public Map<Class<?>, Object> rpcService() {
        return this.cacheService;
    }
}
